package xyj.sparrow.scheduler.aop;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 打印入参\出参\耗时
 *
 * @author 江南小俊
 * @since 2021/6/11 下午11:16
 **/
@Aspect
@Component
@Slf4j
public class LogAop {
    private ThreadLocal<Long> start = new ThreadLocal<>();
    private ThreadLocal<String> sign = new ThreadLocal<>();
    private ThreadLocal<String> args = new ThreadLocal<>();

    @Pointcut("execution(* xyj.sparrow.scheduler.controller.*.*(..))")
    public void log() {
    }

    @Before("log()")
    public void beforeLog(JoinPoint joinPoint) {
        start.set(System.currentTimeMillis());
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();
        sign.set(className + "." + methodName);
        args.set(StrUtil.join(",", joinPoint.getArgs()));
    }

    @AfterReturning(returning = "response", pointcut = "log()")
    public void afterLog(Object response) {
        log.info("\n==> 请求方法: {}" +
                        "\n==> 请求参数: {}" +
                        "\n<==    响应: {}" +
                        "\n<==    耗时: {}ms",
                sign.get(),
                args.get(),
                response,
                System.currentTimeMillis() - start.get());
        sign.remove();
        args.remove();
        start.remove();
    }

}
